package com.ibeeking.found.cop.b.rest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ibeeking.found.cop.b.rest.service.IMsgFansMomentService;
import com.ibeeking.found.cop.b.rest.service.IMsgFansMomentTaskSenderService;
import com.ibeeking.found.cop.b.rest.service.IMsgFansMomentTaskService;
import com.ibeeking.found.cop.b.rest.service.IWxOpenService;
import com.ibeeking.found.cop.service.common.dos.CopEmployeeDO;
import com.ibeeking.found.cop.service.common.dos.MsgFansMomentDO;
import com.ibeeking.found.cop.service.common.dos.MsgFansMomentTaskDO;
import com.ibeeking.found.cop.service.common.enums.WxCpMessageAssignStatusEnum;
import com.ibeeking.found.cop.service.common.enums.WxCpMessageSendWayEnum;
import com.ibeeking.found.cop.service.common.enums.WxCpMessageTypeEnum;
import com.ibeeking.found.cop.service.common.param.MsgFansMomentTaskParam;
import com.ibeeking.found.cop.service.common.query.MsgFansMomentTaskPageQuery;
import com.ibeeking.found.cop.service.common.query.MsgFansMomentTaskQuery;
import com.ibeeking.found.cop.service.common.vo.MsgFansMomentTaskVO;
import com.ibeeking.found.cop.service.mapper.CopEmployeeMapper;
import com.ibeeking.found.cop.service.mapper.MsgFansMomentMapper;
import com.ibeeking.found.cop.service.mapper.MsgFansMomentTaskMapper;
import com.ibeeking.found.id.GenerateId;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.date.DateUtil;
import com.ibeeking.nematos.utils.id.IdGenerator;
import com.ibeeking.nematos.utils.json.JsonUtils;
import me.chanjar.weixin.cp.api.WxCpExternalContactService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.external.WxCpGetMomentList;
import me.chanjar.weixin.cp.bean.external.moment.MomentInfo;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName MsgFansMomentTaskServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-01-27 18:50
 **/
@Service
public class MsgFansMomentTaskServiceImpl extends ServiceImpl<MsgFansMomentTaskMapper, MsgFansMomentTaskDO> implements IMsgFansMomentTaskService {

    @Resource
    private MsgFansMomentMapper msgFansMomentMapper;

    @Resource
    private MsgFansMomentTaskMapper msgFansMomentTaskMapper;

    @Resource
    private CopEmployeeMapper copEmployeeMapper;

    @Resource
    private IMsgFansMomentService msgFansMomentServiceImpl;

    @Resource
    private IMsgFansMomentTaskSenderService msgFansMomentTaskSenderServiceImpl;

    @Resource
    private IWxOpenService wxOpenServiceImpl;

    @Override
    public List<MsgFansMomentTaskVO> list(MsgFansMomentTaskQuery query) {
        List<MsgFansMomentTaskDO> entityDOS = msgFansMomentTaskMapper.selectList(new LambdaQueryWrapper<MsgFansMomentTaskDO>()
                .eq(query.getId() != null, MsgFansMomentTaskDO::getId, query.getId())
                .eq(StringUtils.isNotBlank(query.getType()), MsgFansMomentTaskDO::getType, query.getType())
                .eq(query.getMomentId() != null, MsgFansMomentTaskDO::getMomentId, query.getMomentId())
                .eq(query.getSendWay() != null, MsgFansMomentTaskDO::getSendWay, query.getSendWay())
        );
        List<MsgFansMomentTaskVO> entityVOS =JsonUtils.jsonToList(entityDOS, MsgFansMomentTaskVO.class);
        return entityVOS;
    }

    @Override
    public Page<MsgFansMomentTaskVO> pageList(MsgFansMomentTaskPageQuery pageQuery) {
        LambdaQueryWrapper<MsgFansMomentTaskDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(pageQuery.getId() != null, MsgFansMomentTaskDO::getId, pageQuery.getId())
                .like(StringUtils.isNotBlank(pageQuery.getType()), MsgFansMomentTaskDO::getType, pageQuery.getType())
                .eq(pageQuery.getMomentId() != null, MsgFansMomentTaskDO::getMomentId, pageQuery.getMomentId())
                .eq(pageQuery.getSendWay() != null, MsgFansMomentTaskDO::getSendWay, pageQuery.getSendWay());
        Page<MsgFansMomentTaskDO> entityDOPages = msgFansMomentTaskMapper.selectPage(new Page<MsgFansMomentTaskDO>(pageQuery.getPageNum(), pageQuery.getPageSize()), wrapper);
        Page<MsgFansMomentTaskVO> entityVOPages = BeanUtil.convertPage(entityDOPages, MsgFansMomentTaskVO.class);

        return entityVOPages;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(MsgFansMomentTaskParam param) {
        MsgFansMomentTaskDO entityDO = BeanUtil.convertBean(param, MsgFansMomentTaskDO.class);
        entityDO.setId(GenerateId.generateId());
        return msgFansMomentTaskMapper.insert(entityDO) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean modify(MsgFansMomentTaskParam param) {
        MsgFansMomentTaskDO entityDO = BeanUtil.convertBean(param, MsgFansMomentTaskDO.class);
        return msgFansMomentTaskMapper.updateById(entityDO) > 0;
    }

    @Override
    public MsgFansMomentTaskVO view(Long id) {
        MsgFansMomentTaskDO entityDO = msgFansMomentTaskMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        MsgFansMomentTaskVO entityVO = BeanUtil.convertBean(entityDO, MsgFansMomentTaskVO.class);

        return entityVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean del(Long id) {
        MsgFansMomentTaskDO entityDO = msgFansMomentTaskMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        return msgFansMomentTaskMapper.deleteById(id) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean syncFansMomentTaskRecordFromWxCp(Integer tenantId, String beginDate, String endDate){
        try {
            WxCpService wxCpService = wxOpenServiceImpl.getWxCpService(tenantId.longValue());
            WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
            if (wxCpConfigStorage == null) {
                throw new BusinessException("获取企微服务失败!");
            }
            LogUtils.info("====process wxCpConfigStorage:{}====", JsonUtils.toJsonStr(wxCpConfigStorage));

            WxCpExternalContactService wxCpExternalContactService = wxCpService.getExternalContactService();
            if (wxCpExternalContactService == null) throw new BusinessException("获取企微服务外部联系人服务!");
            LocalDateTime  beginDateTime = DateUtil.strToLocalDateTime(beginDate);
            LocalDateTime  endDateTime = DateUtil.strToLocalDateTime(endDate);
            if(beginDateTime!=null && endDateTime!=null) {
                List<String> allComentCodes = new ArrayList<>();
                List<MsgFansMomentDO> needInsertMsgFansMomentDOS = new ArrayList<>();
                List<MsgFansMomentDO> needUpdateMsgFansMomentDOS = new ArrayList<>();
                List<CopEmployeeDO> copEmployeeDOS = copEmployeeMapper.selectList(new LambdaQueryWrapper<>());
                Map<String, Long> copEmployeeNameMaps = Collections3.isNotEmpty(copEmployeeDOS)?copEmployeeDOS.stream().collect(Collectors.toMap(CopEmployeeDO::getEmployeeCode, CopEmployeeDO::getId, (o, n) -> n)):null;

                List<MsgFansMomentDO> allMsgFansMomentDOS = msgFansMomentMapper.selectList(new LambdaQueryWrapper<MsgFansMomentDO>());
                Map<String,MsgFansMomentDO> allMsgFansMomentCodeMap = Collections3.isNotEmpty(allMsgFansMomentDOS)?allMsgFansMomentDOS.stream().collect(Collectors.toMap(MsgFansMomentDO::getRtnMomentId, x->x, (o, n) -> n)):null;
                int days = DateUtil.days(beginDateTime, endDateTime);
                for(long i = 0;i*29 < days;i ++) {
                    Long beginDateTimeLong = Timestamp.valueOf(beginDateTime.plusDays(i * 29)).getTime();
                    Long endDateTimeLong = 0L;
                    if(days - (i*29) <= 29) {
                        endDateTimeLong = Timestamp.valueOf(beginDateTime.plusDays(days - i*29)).getTime();
                    }else {
                        endDateTimeLong = Timestamp.valueOf(beginDateTime.plusDays((i + 1) * 29)).getTime();
                    }
                    String nextCursor = null;
                    do {
                        WxCpGetMomentList wxCpGetMomentList = wxCpExternalContactService.getMomentList(beginDateTimeLong, endDateTimeLong, null, 2, nextCursor, 20);
                        LogUtils.info("====process wxCpGetMomentList:{}====", JsonUtils.toJsonStr(wxCpGetMomentList));
                        if (wxCpGetMomentList != null) {
                            nextCursor = wxCpGetMomentList.getNextCursor();
                            List<MomentInfo> momentInfoList = wxCpGetMomentList.getMomentList();
                            for (MomentInfo momentInfo : momentInfoList) {
                                String momentCode = momentInfo.getMomentId();
                                allComentCodes.add(momentCode);
                                if(allMsgFansMomentCodeMap!=null && allMsgFansMomentCodeMap.containsKey(momentCode)) {
                                    MsgFansMomentDO updateMomentDO = allMsgFansMomentCodeMap.get(momentCode);
                                    String createTime = momentInfo.getCreateTime();
                                    if(StringUtils.isNotEmpty(createTime)) {
                                        updateMomentDO.setBuidTime(DateUtil.longToLocalDateTime(Long.valueOf(createTime)));
                                    }
                                    updateMomentDO.setBuildType(momentInfo.getCreateType());
                                    if(StringUtils.isNotEmpty(momentInfo.getCreator())) {
                                        updateMomentDO.setBuilderCode(momentInfo.getCreator());
                                        updateMomentDO.setBuilderId(copEmployeeNameMaps!=null?copEmployeeNameMaps.get(momentInfo.getCreator()):null);
                                    }
                                    updateMomentDO.setVisibleType(momentInfo.getVisibleType());
                                    List<me.chanjar.weixin.cp.bean.external.msg.Image> momentImageList = momentInfo.getImage();
                                    me.chanjar.weixin.cp.bean.external.msg.Link momentLink = momentInfo.getLink();
                                    me.chanjar.weixin.cp.bean.external.msg.Text momentText = momentInfo.getText();
                                    me.chanjar.weixin.cp.bean.external.msg.Video momentVideo = momentInfo.getVideo();
                                    me.chanjar.weixin.cp.bean.external.msg.Location momentLocation = momentInfo.getLocation();
                                    updateMomentDO.setModifyTime(LocalDateTime.now());
                                    needUpdateMsgFansMomentDOS.add(updateMomentDO);
                                }else{
                                    MsgFansMomentDO updateMomentDO = new MsgFansMomentDO();
                                    Long momentId = IdGenerator.getId();
                                    updateMomentDO.setSendCycle(1);
                                    updateMomentDO.setType(WxCpMessageTypeEnum.MESSAGE_MOMENT_TYPE_ADD_TASK.getCode());
                                    updateMomentDO.setSendStatus(WxCpMessageAssignStatusEnum.MESSAGE_ASSIGN_STATUS_ASSIGNED.getCode());
                                    updateMomentDO.setSendWay(WxCpMessageSendWayEnum.MESSAGE_SEND_WAY_NOW.getCode());
                                    updateMomentDO.setId(momentId);
                                    updateMomentDO.setRtnMomentId(momentCode);
                                    String createTime = momentInfo.getCreateTime();
                                    if(StringUtils.isNotEmpty(createTime)) {
                                        updateMomentDO.setBuidTime(DateUtil.longToLocalDateTime(Long.valueOf(createTime)));
                                        updateMomentDO.setSendTime(DateUtil.longToLocalDateTime(Long.valueOf(createTime)));
                                    }
                                    updateMomentDO.setBuildType(momentInfo.getCreateType());
                                    if(StringUtils.isNotEmpty(momentInfo.getCreator())) {
                                        updateMomentDO.setBuilderCode(momentInfo.getCreator());
                                        updateMomentDO.setBuilderId(copEmployeeNameMaps!=null?copEmployeeNameMaps.get(momentInfo.getCreator()):null);
                                    }
                                    updateMomentDO.setVisibleType(momentInfo.getVisibleType());
                                    me.chanjar.weixin.cp.bean.external.msg.Text momentText = momentInfo.getText();
                                    if(momentText!=null){
                                        String momentContent = momentText.getContent();
                                        if(StringUtils.isNotEmpty(momentContent)) {
                                            updateMomentDO.setContent(momentContent);
                                            updateMomentDO.setName(StringUtils.substring(momentContent,0,10));
                                        }
                                    }
                                    List<me.chanjar.weixin.cp.bean.external.msg.Image> momentImageList = momentInfo.getImage();
                                    me.chanjar.weixin.cp.bean.external.msg.Link momentLink = momentInfo.getLink();
                                    me.chanjar.weixin.cp.bean.external.msg.Video momentVideo = momentInfo.getVideo();
                                    me.chanjar.weixin.cp.bean.external.msg.Location momentLocation = momentInfo.getLocation();
                                    updateMomentDO.setCreateTime(LocalDateTime.now());
                                    updateMomentDO.setModifyTime(LocalDateTime.now());
                                    needInsertMsgFansMomentDOS.add(updateMomentDO);
                                }
                            }
                        } else {
                            nextCursor = null;
                        }
                    } while (nextCursor == null);
                }
                if(Collections3.isNotEmpty(needInsertMsgFansMomentDOS)){
                    msgFansMomentMapper.insertBatchSomeColumn(needInsertMsgFansMomentDOS);
                }
                if(Collections3.isNotEmpty(needUpdateMsgFansMomentDOS)){
                    msgFansMomentServiceImpl.updateBatch(needUpdateMsgFansMomentDOS);
                }
                if(Collections3.isNotEmpty(allComentCodes)){
                    msgFansMomentTaskSenderServiceImpl.syncFansMomentTaskSenderListFromWxCp(tenantId, allComentCodes);

                }

            }
            return true;
        } catch (Exception e) {
            throw new BusinessException("获取企微服务失败!");
        }
    }
}
